package com.example.commonlib.httplib;

import android.content.Context;
import android.support.annotation.NonNull;

import com.example.commonlib.commonutil.MLog;
import com.example.commonlib.httplib.interceptor.BasicParamsInterceptor;
import com.example.commonlib.httplib.interceptor.CacheInterceptor;
import com.example.commonlib.httplib.interceptor.UrlInterceptor;
import com.example.commonlib.httplib.utils.ResponseConverterFactory;
import com.example.commonlib.httplib.utils.StringDefaultAdapter;
import com.facebook.stetho.okhttp3.StethoInterceptor;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

/**
 * Create by xjs
 * _______date : 17/8/2
 * _______description:
 */
public class RetrofitManager {

    private static RetrofitManager retrofitManager;

    private OkHttpClient okHttpClient;

    private Retrofit retrofit;

    //缓存对象
    private Cache cache;

    //日志拦截器
    public HttpLoggingInterceptor httpLoggingInterceptor;

    //url拦截器
    public UrlInterceptor urlInterceptor = new UrlInterceptor();

    //全局上下文
    public Context context;

    //添加基础参数
    public BasicParamsInterceptor basicParamsInterceptor;

    private RetrofitManager(Context context) {
        this.context = context;
    }

    /**
     * 同步锁，解决多线程初始化
     *
     * @param context
     * @return
     */
    public static RetrofitManager getInstance(Context context) {
        if (retrofitManager == null) {
            synchronized (RetrofitManager.class) {
                if (retrofitManager == null) {
                    retrofitManager = new RetrofitManager(context);
                }
            }
        }
        return retrofitManager;
    }

    /**
     * initURL
     *
     * @return
     */
    public RetrofitManager init() {
        urlInterceptor.context = context;
        return this;
    }

    /**
     * 创建retrofit
     *
     * @param service
     * @param <T>
     * @return
     */
    public <T> T getApiService(Class<T> service) {
        return retrofit.create(service);
    }

    public static Api build(Context context){
        return getInstance(context).getApiService(Api.class);
    }
    /**
     * 获取缓存
     *
     * @return
     */
    public Cache getCache() {
        return cache;
    }

    /**
     * 删除缓存
     *
     * @throws IOException
     */
    public void clearCache() throws IOException {
        cache.delete();
    }

    public void initRetrofit(String baseUrl) {
        urlInterceptor.hostInit = baseUrl;
        //初始化缓存token
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(String.class, new StringDefaultAdapter())
                .setLenient()
                .create();
        retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(ResponseConverterFactory.create(gson))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(okHttpClient)
                .build();
    }

    public RetrofitManager initOkHttp() {
        basicParamsInterceptor = new BasicParamsInterceptor.Builder().build();

        File cacheFile = new File(context.getCacheDir(), "okhttpCache");
        cache = new Cache(cacheFile, 1024 * 1024 * 100);  //100M
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(@NonNull String message) {
                //打印retrofit日志
                MLog.e("retrofitBack = ", message);
            }
        });
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        builder.addNetworkInterceptor(new StethoInterceptor());

        okHttpClient = builder.connectTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)  //重连
                .addInterceptor(urlInterceptor)
                .addInterceptor(httpLoggingInterceptor)
                .addInterceptor(new CacheInterceptor())
                .addInterceptor(basicParamsInterceptor)
                .addNetworkInterceptor(new StethoInterceptor())  //stetho网络拦截器
                .cache(cache)
                //.proxy(Proxy.NO_PROXY)
                .build();
        return this;
    }
}
